package com.example.user.test2;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Switch;
import android.widget.TextView;

import com.theta360.lib.PtpipInitiator;
import com.theta360.lib.ThetaException;
import com.theta360.lib.ptpip.entity.DeviceInfo;
import com.theta360.lib.ptpip.entity.ObjectInfo;
import com.theta360.lib.ptpip.entity.PtpObject;
import com.theta360.lib.ptpip.entity.Response;
import com.theta360.lib.ptpip.eventlistener.PtpipEventListener;
import com.theta360.lib.ptpip.settingvalue.ISOSpeed;
import com.theta360.lib.ptpip.settingvalue.ShutterSpeed;
import com.theta360.lib.ptpip.settingvalue.WhiteBalance;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;

public class MainActivity extends AppCompatActivity {


    private TextView mText;
    private Switch connectionSwitch;

    private ProgressBar mProgressBar;
    private PtpipInitiator camera;


//    private com.example.user.test2.ThetaInitiator tc;



    //////////////////////////////////////////////////////////////////////////////////
    public static final WhiteBalance wbmap[]={
            WhiteBalance.OUTSIDE,WhiteBalance.SHADE,WhiteBalance.CLOUDINESS,
            WhiteBalance.INCANDESCENT_LAMP1,WhiteBalance.INCANDESCENT_LAMP2,
            WhiteBalance.FLUORESCENT_LAMP1, WhiteBalance.FLUORESCENT_LAMP2,
            WhiteBalance.FLUORESCENT_LAMP3,WhiteBalance.FLUORESCENT_LAMP4,
            WhiteBalance.AUTO
    };

    public static boolean wbselection[] ={
            false,false,false,false,
            false,false,false,false,
            false
    };

    //////////////////////////////////////////////////////////////////////////////////

    public static final ISOSpeed isomap[] ={
            ISOSpeed.ISO100,ISOSpeed.ISO125,ISOSpeed.ISO160,
            ISOSpeed.ISO200,ISOSpeed.ISO250,ISOSpeed.ISO320,ISOSpeed.ISO400,
            ISOSpeed.ISO500,ISOSpeed.ISO640,ISOSpeed.ISO800,ISOSpeed.ISO1000,
            ISOSpeed.ISO1250,ISOSpeed.ISO1600,ISOSpeed.AUTO
    };

    public static boolean isoselection[] ={
            false,false,false,false,
            false,false,false,false,
            false,false,false,false,
            false
    };

    ///////////////////////////////////////////////////////////////////////////////////////
    public static final ShutterSpeed ssmap[] ={
            ShutterSpeed.SPEED1_8000,ShutterSpeed.SPEED1_6400,ShutterSpeed.SPEED1_5000,
            ShutterSpeed.SPEED1_4000,ShutterSpeed.SPEED1_3200,ShutterSpeed.SPEED1_2500,ShutterSpeed.SPEED1_2000,
            ShutterSpeed.SPEED1_1600,ShutterSpeed.SPEED1_1250,ShutterSpeed.SPEED1_1000,ShutterSpeed.SPEED1_800,
            ShutterSpeed.SPEED1_640,ShutterSpeed.SPEED1_500,ShutterSpeed.SPEED1_400,ShutterSpeed.SPEED1_320,
            ShutterSpeed.SPEED1_250,ShutterSpeed.SPEED1_200,ShutterSpeed.SPEED1_160,ShutterSpeed.SPEED1_125,
            ShutterSpeed.SPEED1_100,ShutterSpeed.SPEED1_80,ShutterSpeed.SPEED1_60,ShutterSpeed.SPEED1_50,
            ShutterSpeed.SPEED1_40,ShutterSpeed.SPEED1_30,ShutterSpeed.SPEED1_25,ShutterSpeed.SPEED1_20,
            ShutterSpeed.SPEED1_15,ShutterSpeed.SPEED1_13,ShutterSpeed.SPEED1_10,ShutterSpeed.SPEED10_75,
            ShutterSpeed.AUTO
    };

    public static boolean ssselection[] ={
            false,false,false,false,false,false,false,
            false,false,false,false,false,false,false,false,
            false,false,false,false,false,false,false,false,
            false,false,false,false,false,false,false,false
    };

    ////////////////////////////////////////////////////////////////////////////////
    public static final int evmap[] ={
            -2000, -1700, -1300, -1000,
            -700, -300, 0, 300, 700,
            1000, 1300, 1700, 2000
    };

    public static boolean evselection[] ={
            false,false,false,false,
            false,false,true,false,false,
            false,false,false,false
    };

///////////////////////////////////////////////////////////////////////////////////////////////

    public static ArrayList<Integer> propertyIdx;

    public static ArrayList<Integer> settingIdx;

//    public static ArrayList<String> resultMsg;

    public static int isbusy=-1;

    public static int FirstTrue(boolean chk[])
    {
        int i=0;
        while (i<chk.length && !chk[i])
        {
            i++;
        }
        return i;
    }

    public static int BracketNum(boolean chk[])
    {
        int n=0;
        for(int i=0;i<chk.length;i++)
        {
            if(chk[i])
                n++;
        }
        return n;
    }


    public static int BracketList(boolean chk[], ArrayList<Integer> bklist)
    {
        bklist.clear();
        for(int i=0;i<chk.length;i++)
        {
            if(chk[i])
               bklist.add(i);
        }
        return bklist.size();
    }


    public static void AddList(ArrayList<Integer> l, ArrayList<Integer> a,
                               ArrayList<Integer> la, int mark[], boolean flip[])
    {
        int lan=la.size();
        if(lan<2)
            return;
        if(flip[0])
        {
            for(int j=lan-2;j>=0;j--)
            {
                l.add(la.get(j));
                a.add(mark[0]);
            }
        }
        else
        {
            for(int j=1;j<lan;j++)
            {
                l.add(la.get(j));
                a.add(mark[0]);
            }
        }
        flip[0]=!flip[0];
    }

    public static void AddList(ArrayList<Integer> l, ArrayList<Integer> ab,
                               ArrayList<Integer> la, ArrayList<Integer> lb,
                               int mark[], boolean flip[])
    {
        AddList(l,ab,la,mark,flip);
        int lbn=lb.size();
        if(lbn<2)
            return;
        if(flip[1])
        {
            for(int j=lbn-2;j>=0;j--)
            {
                l.add(lb.get(j));
                ab.add(mark[1]);
                AddList(l,ab,la,mark,flip);
            }
        }
        else
        {
            for(int j=1;j<lbn;j++)
            {
                l.add(lb.get(j));
                ab.add(mark[1]);
                AddList(l,ab,la,mark,flip);
            }
        }
        flip[1]=!flip[1];
    }


    public static void AddList(ArrayList<Integer> l, ArrayList<Integer> abc,
                               ArrayList<Integer> la, ArrayList<Integer> lb, ArrayList<Integer> lc,
                               int mark[], boolean flip[])
    {
        AddList(l,abc,la,lb,mark,flip);
        int lcn=lc.size();
        if(lcn<2)
            return;
        if(flip[2])
        {
            for(int j=lcn-2;j>=0;j--)
            {
                l.add(lc.get(j));
                abc.add(mark[2]);
                AddList(l,abc,la,lb,mark,flip);
            }
        }
        else
        {
            for(int j=1;j<lcn;j++)
            {
                l.add(lc.get(j));
                abc.add(mark[2]);
                AddList(l,abc,la,lb,mark,flip);
            }
        }
        flip[2]=!flip[2];
    }





    public static void BracketList()
    {
        ArrayList<Integer> wbl=new ArrayList<Integer>();
        int wbn=BracketList(wbselection,wbl);
        ArrayList<Integer> isol=new ArrayList<Integer>();
        int ison=BracketList(isoselection, isol);
        ArrayList<Integer> ssl=new ArrayList<Integer>();
        int ssn=BracketList(ssselection, ssl);
        ArrayList<Integer> evl=new ArrayList<Integer>();
        int evn=BracketList(evselection,evl);

        boolean flg[]={false,false,false};
        propertyIdx.clear();
        settingIdx.clear();

        if(ison==0)
        {
            //ev,ss,wb bracket
            int pptIndex[]={3,2,0};
            AddList(settingIdx,propertyIdx,evl,ssl,wbl,pptIndex,flg);
            return;
        }
        if(ssn==0)
        {
            //ev, iso, wb bracket
            int pptIndex[]={3,1,0};
            AddList(settingIdx,propertyIdx,evl,isol,wbl,pptIndex,flg);
            return;
        }
        //iso, ss, wb bracket
        int pptIndex[] = {2, 1, 0};
        AddList(settingIdx,propertyIdx,ssl,isol,wbl,pptIndex,flg);
    }

    public String SettingStr(int pptindex, int stindex)
    {

        switch(pptindex)
        {
            case 0:
                if(stindex<0 || stindex>wbselection.length)
                    return "?";
                if(stindex==wbselection.length)
                    return getResources().getString(R.string.auto);
                return getResources().getStringArray(R.array.wbitems)[stindex];
            case 1:
                if(stindex<0 || stindex>isoselection.length)
                    return "?";
                if(stindex==isoselection.length)
                    return getResources().getString(R.string.auto);
                return getResources().getStringArray(R.array.isoitems)[stindex];
            case 2:
                if(stindex<0 || stindex>ssselection.length)
                    return "?";
                if(stindex==ssselection.length)
                    return getResources().getString(R.string.auto);
                return getResources().getStringArray(R.array.ssitems)[stindex];
            case 3:
                if(stindex<0 || stindex>=evselection.length)
                    return "?";
                return getResources().getStringArray(R.array.evitems)[stindex];
            case 4:
            case 5:
            case 6:
                if(stindex<0)
                    return "?";
                return String.valueOf(stindex);
        }

        return "?";
    }



    private class GetPropertyTask extends AsyncTask<Integer, Void, Boolean> {

        public int GetProperty(int pptindex)
        {
            try {
                switch(pptindex)
                {
                    case 0:
                    {
                        for(int i=0;i<wbselection.length;i++)
                            wbselection[i]=false;
                        WhiteBalance st=camera.getWhiteBalance();
                        for(int i=0;i<wbmap.length;i++)
                            if(st==wbmap[i])
                            {
                                if(i<wbselection.length)
                                    wbselection[i]=true;
                                return i;
                            }

                        return -1;
                    }
                    case 1:
                    {
                        for(int i=0;i<isoselection.length;i++)
                            isoselection[i]=false;
                        ISOSpeed st=camera.getExposureIndex();
                        for(int i=0;i<isomap.length;i++)
                            if(st==isomap[i])
                            {
                                if(i<isoselection.length)
                                    isoselection[i]=true;
                                return i;
                            }
                        return -1;
                    }
                    case 2:
                    {
                        for(int i=0;i<ssselection.length;i++)
                            ssselection[i]=false;
                        ShutterSpeed st=camera.getShutterSpeed();
                        for(int i=0;i<ssmap.length;i++)
                            if(st==ssmap[i])
                            {
                                if(i<ssselection.length)
                                    ssselection[i]=true;
                                return i;
                            }
                        return -1;
                    }
                    case 3:
                    {
                        for(int i=0;i<evselection.length;i++)
                            evselection[i]=false;
                        int st=camera.getExposureBiasCompensation();
                        for(int i=0;i<evmap.length;i++)
                            if(st==evmap[i])
                            {
                                evselection[i]=true;
                                return i;
                            }
                        return -1;
                    }
                    case 4:
                        return camera.getAudioVolume();
                    case 5:
                        return camera.getAutoPowerOffDelay();
                    case 6:
                        return camera.getSleepDelay();
                }
            } catch (ThetaException e) {
                e.printStackTrace();
            }
            return -1;
        }

        private int index;

        private int resultIndex;

        public GetPropertyTask(int idx) {
            this.index = idx;
        }

        @Override
        protected Boolean doInBackground(Integer... params) {
            resultIndex=GetProperty(propertyIdx.get(index));
            return true;
        }

        protected void onProgressUpdate(Integer... progress) {//在调用publishProgress之后被调用，在ui线程执行
//            mProgressBar.setProgress(progress[0]);//更新进度条的进度
        }

        protected void onPostExecute(Boolean result) {//后台任务执行完之后被调用，在ui线程执行

            if(index+1<propertyIdx.size())
            {
                new GetPropertyTask(index+1).execute();
                mButtonP[propertyIdx.get(index)].settingIndex=resultIndex;
                mButtonP[propertyIdx.get(index)].UpdateText();
                return;
            }

            mButtonP[propertyIdx.get(index)].settingIndex=resultIndex;
            mButtonP[propertyIdx.get(index)].UpdateText();
            isbusy=-1;
        }

        protected void onPreExecute () {//在 doInBackground(Params...)之前被调用，在ui线程执行
//            mProgressBar.setProgress(0);//进度条复位
            isbusy=0;
//            resultMsg.clear();
        }

        protected void onCancelled () {//在ui线程执行
//            mProgressBar.setProgress(0);//进度条复位
            isbusy=-1;
        }

    }



    public class SetPropertyTask extends AsyncTask<Integer, Void, Boolean> {

        public boolean SetProperty(int pptindex, int stindex)
        {
            try {
                switch(pptindex)
                {
                    case 0:
                        camera.setWhiteBalance(wbmap[stindex]);
                        return true;
                    case 1:
                        camera.setExposureIndex(isomap[stindex]);
                        return true;
                    case 2:
                        camera.setShutterSpeed(ssmap[stindex]);
                        return true;
                    case 3:
                        camera.setExposureBiasCompensation((short)evmap[stindex]);
                        return true;
                    case 4:
                        camera.setAudioVolume(stindex);
                        return true;
                    case 5:
                        camera.setAutoPowerOffDelay(stindex);
                        return true;
                    case 6:
                        camera.setSleepDelay((short)stindex);
                        return true;
                }
            } catch (ThetaException e) {
                e.printStackTrace();
            }
            return false;
        }

        private int index;

        public SetPropertyTask(int idx) {
            this.index = idx;
        }

        @Override
        protected Boolean doInBackground(Integer... params) {
            return SetProperty(propertyIdx.get(index),settingIdx.get(index));
        }

        protected void onProgressUpdate(Integer... progress) {//在调用publishProgress之后被调用，在ui线程执行
//            mProgressBar.setProgress(progress[0]);//更新进度条的进度
        }

        protected void onPostExecute(Boolean result) {//后台任务执行完之后被调用，在ui线程执行
//            if(result) {
//                resultMsg.add(PropertySettingStr(propertyIdx.get(index),settingIdx.get(index)));
//            }
//            else
//            {
//                resultMsg.add(PropertySettingStr(propertyIdx.get(index), -1));
//            }

            mButtonP[propertyIdx.get(index)].settingIndex=settingIdx.get(index);
            mButtonP[propertyIdx.get(index)].UpdateText();

            index++;
            if(index<propertyIdx.size())
            {
                new SetPropertyTask(index).execute();
                return;
            }
            isbusy=-1;

        }

        protected void onPreExecute () {//在 doInBackground(Params...)之前被调用，在ui线程执行
//            mProgressBar.setProgress(0);//进度条复位
            isbusy=0;
//            resultMsg.clear();
        }

        protected void onCancelled () {//在ui线程执行
//            mProgressBar.setProgress(0);//进度条复位
            isbusy=-1;
        }

    }



    public class ThetaButton
    {
        public Button mButton;

        public int propertyIndex;
        public int settingIndex;

        public void Setup(int idx)
        {
            this.propertyIndex = idx;
            mButton.setOnClickListener(new ThetaButtonOnClickListener()); // 设置监听者的类
        }

        public void UpdateText()
        {
            String propertyShortStr=getResources().getStringArray(R.array.pptitems)[propertyIndex];
            String bknstr;
            switch(propertyIndex)
            {
                case 0:
                    bknstr="["+String.valueOf(BracketNum(wbselection))+"]";
                    break;
                case 1:
                    bknstr="["+String.valueOf(BracketNum(isoselection))+"]";
                    break;
                case 2:
                    bknstr="["+String.valueOf(BracketNum(ssselection))+"]";
                    break;
                case 3:
                    bknstr="["+String.valueOf(BracketNum(evselection))+"]";
                    break;
                default:
                    bknstr="";
                    break;
            }

            mButton.setText(propertyShortStr + " " + SettingStr(propertyIndex, settingIndex) + bknstr);
        }

        class ListOnClickYesListener implements DialogInterface.OnClickListener{
            @Override
            public void onClick(DialogInterface dialog, int which) {

                settingIndex=0;
                switch(propertyIndex)
                {
                    case 0:
                        settingIndex=FirstTrue(wbselection);
                        break;
                    case 1:
                        settingIndex=FirstTrue(isoselection);
                        break;
                    case 2:
                        settingIndex=FirstTrue(ssselection);
                        break;
                    case 3:
                        settingIndex=FirstTrue(evselection);
                        if(settingIndex>=evselection.length)
                        {
                            settingIndex = 6;
                            evselection[settingIndex]=true;
                        }
                        break;
                    case 4:
                        settingIndex=which;
                    break;
                    case 5:
                        settingIndex=which;
                        break;
                    case 6:
                        settingIndex=which;
                        break;
                }

                propertyIdx.clear();
                propertyIdx.add(propertyIndex);
                settingIdx.clear();
                settingIdx.add(settingIndex);

                new SetPropertyTask(0).execute();
            }
        }

        class MultiChoiceListOnClickListener implements DialogInterface.OnMultiChoiceClickListener{

            @Override
            public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                switch(propertyIndex)
                {
                    case 0:
                        wbselection[which]=isChecked;
                        return;
                    case 1:
                        isoselection[which]=isChecked;
                        return;
                    case 2:
                        ssselection[which]=isChecked;
                        return;
                    case 3:
                        evselection[which]=isChecked;
                        return;
                }

            }
        }

        class SingleChoiceListOnClickListener implements DialogInterface.OnClickListener{
            @Override
            public void onClick(DialogInterface dialog, int which) {
//                new SetISOTask(which).execute();
            }
        }

        class ThetaButtonOnClickListener implements View.OnClickListener { // 接口的第一个实现
            public void onClick(View v) {

                switch(propertyIndex)
                {
                    case 0:
                        new AlertDialog.Builder(MainActivity.this)
                                .setTitle(R.string.white_balance)
                                .setMultiChoiceItems(R.array.wbitems, wbselection, new MultiChoiceListOnClickListener())
                                .setPositiveButton(R.string.yes, new ListOnClickYesListener())
                                .show();
                        return;
                    case 1:
                        new AlertDialog.Builder(MainActivity.this)
                                .setTitle(R.string.iso_speed)
                                .setMultiChoiceItems(R.array.isoitems, isoselection, new MultiChoiceListOnClickListener())
                                .setPositiveButton(R.string.yes, new ListOnClickYesListener())
                                .show();
                        return;
                    case 2:
                        new AlertDialog.Builder(MainActivity.this)
                                .setTitle(R.string.shutter_speed)
                                .setMultiChoiceItems(R.array.ssitems, ssselection, new MultiChoiceListOnClickListener())
                                .setPositiveButton(R.string.yes, new ListOnClickYesListener())
                                .show();
                        return;
                    case 3:
                        new AlertDialog.Builder(MainActivity.this)
                                .setTitle(R.string.exposure_bias_compensation)
                                .setMultiChoiceItems(R.array.evitems, evselection, new MultiChoiceListOnClickListener())
                                .setPositiveButton(R.string.yes, new ListOnClickYesListener())
                                .show();
                        return;
                    case 4:
                        new AlertDialog.Builder(MainActivity.this)
                                .setTitle(R.string.shutter_volume)
                                .setItems(R.array.svitems, new ListOnClickYesListener())
                                .show();
                        return;
                    case 5:
                        new AlertDialog.Builder(MainActivity.this)
                                .setTitle(R.string.auto_power_off_delay)
                                .setItems(R.array.pditems,new ListOnClickYesListener())
                                .show();
                        return;
                    case 6:
                        new AlertDialog.Builder(MainActivity.this)
                                .setTitle(R.string.sleep_delay)
                                .setItems(R.array.sditems,new ListOnClickYesListener())
                                .show();
                        return;
                    default:
                        new AlertDialog.Builder(MainActivity.this)
                                .setTitle(R.string.iso_speed)
                                .setItems(R.array.isoitems, new SingleChoiceListOnClickListener())
                                .show();
                        return;
                }


            }
        }

    }



    private ThetaButton mButtonP[]={new ThetaButton(),new ThetaButton(),new ThetaButton(),new ThetaButton(),new ThetaButton(),new ThetaButton(),new ThetaButton()};

    /////////////////////////////////////////////////////////////////////////////////
    private class ConnectTask extends AsyncTask<String,Integer,Boolean>{

        private String model;
        @Override
        protected Boolean doInBackground(String... params){

            try {
                publishProgress(0);//将会调用onProgressUpdate(Integer... progress)方法
                camera = new PtpipInitiator("192.168.1.1");
                publishProgress(50);//将会调用onProgressUpdate(Integer... progress)方法
                DeviceInfo deviceInfo = camera.getDeviceInfo();
                model = deviceInfo.getModel();
                publishProgress(100);//将会调用onProgressUpdate(Integer... progress)方法


                short stillCaptureMode=camera.getStillCaptureMode();
                switch(stillCaptureMode)
                {
                    case PtpipInitiator.DEVICE_PROP_VALUE_UNDEFINED_CAPTURE_MODE:
                        return false;
                    case PtpipInitiator.DEVICE_PROP_VALUE_TIMELAPSE_CAPTURE_MODE:
                        camera.setStillCaptureMode(PtpipInitiator.DEVICE_PROP_VALUE_SINGLE_CAPTURE_MODE);
                        return true;
                    case PtpipInitiator.DEVICE_PROP_VALUE_SINGLE_CAPTURE_MODE:
                        return true;
                }


                return true;
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ThetaException e) {
                e.printStackTrace();
            }
            return false;
        }

        protected void onProgressUpdate(Integer... progress) {//在调用publishProgress之后被调用，在ui线程执行
            mProgressBar.setProgress(progress[0]);//更新进度条的进度
        }

        protected void onPostExecute(Boolean result) {//后台任务执行完之后被调用，在ui线程执行
            if(result) {

                connectionSwitch.setText(model);

//                new GetWBTask().execute();
//                new GetISOTask().execute();
//                new GetSSTask().execute();
//                new GetEVTask().execute();

                propertyIdx.clear();
                propertyIdx.add(0);
                propertyIdx.add(1);
                propertyIdx.add(2);
                propertyIdx.add(3);
                propertyIdx.add(4);
                propertyIdx.add(5);
                propertyIdx.add(6);

                new GetPropertyTask(0).execute();

            }else {
                connectionSwitch.setText("fail");
            }
        }

        protected void onPreExecute () {//在 doInBackground(Params...)之前被调用，在ui线程执行
            connectionSwitch.setText("connecting");
            mProgressBar.setProgress(0);//进度条复位
        }

        protected void onCancelled () {//在ui线程执行
            mProgressBar.setProgress(0);//进度条复位
        }


    }

    private class DisConnectTask extends AsyncTask<Void, Integer, Boolean> {
        @Override
        protected Boolean doInBackground(Void... params) {
            try {
                publishProgress(0);//将会调用onProgressUpdate(Integer... progress)方法
                camera.close();
                publishProgress(100);//将会调用onProgressUpdate(Integer... progress)方法
                return true;
            } catch (ThetaException e) {
                e.printStackTrace();
            }
            return false;
        }

        protected void onProgressUpdate(Integer... progress) {//在调用publishProgress之后被调用，在ui线程执行
            mProgressBar.setProgress(progress[0]);//更新进度条的进度
        }

        protected void onPostExecute(Boolean result) {//后台任务执行完之后被调用，在ui线程执行
            if(result) {
                connectionSwitch.setText("off");
            }else {
                connectionSwitch.setText("fail");
            }
        }

        protected void onPreExecute () {//在 doInBackground(Params...)之前被调用，在ui线程执行
            connectionSwitch.setText("disconnecting");
            mProgressBar.setProgress(0);//进度条复位
        }

        protected void onCancelled () {//在ui线程执行
            mProgressBar.setProgress(0);//进度条复位
        }

    }

    class ConnectOnCheckedChangeListener implements CompoundButton.OnCheckedChangeListener{

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked) {
                new ConnectTask().execute();
            } else {
                new DisConnectTask().execute();
            }
        }
    }

/////////////////////////////////////////////////////////////////////////////////////////////////////////

    public static String folder="thetaj";

    public void writeSDFile(String fileName,  byte [] bytes) throws IOException
    {
        String f = Environment.getExternalStorageDirectory().getPath();//获取SD卡目录
        String sDir="thetaj";
        File destDir = new File(f+"/"+sDir);
        if (!destDir.exists()) {
            destDir.mkdirs();
        }
        File file = new File(f+"/"+sDir+"/"+fileName);
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(bytes);
        fos.close();
    }

    private class GetThumbnailTask extends AsyncTask<Void, Integer, Void> {

        private int objectHandle;

        public GetThumbnailTask(int objectHandle) {
            this.objectHandle = objectHandle;
        }

        @Override
        protected Void doInBackground(Void... params) {

            publishProgress(0);//将会调用onProgressUpdate(Integer... progress)方法
            ObjectInfo objectInfo = null;
            try {
                objectInfo = camera.getObjectInfo(objectHandle);
            } catch (ThetaException e) {
                e.printStackTrace();
            }
            String filename=objectInfo.getFilename();
            publishProgress(10);//将会调用onProgressUpdate(Integer... progress)方法
            byte[] object= new byte[0];
            try {
                object = camera.getObject(objectHandle);
            } catch (ThetaException e) {
                e.printStackTrace();
            }
            publishProgress(60);//将会调用onProgressUpdate(Integer... progress)方法
            try {
                writeSDFile(filename,object);
            } catch (IOException e) {
                e.printStackTrace();
            }
            publishProgress(100);//将会调用onProgressUpdate(Integer... progress)方法
            return null;
        }


        protected void onProgressUpdate(Integer... progress) {//在调用publishProgress之后被调用，在ui线程执行
            mProgressBar.setProgress(progress[0]);//更新进度条的进度
        }

        protected void onPostExecute(Void result) {//后台任务执行完之后被调用，在ui线程执行
            mText.setText("transfer complete");
        }

        protected void onPreExecute () {//在 doInBackground(Params...)之前被调用，在ui线程执行
            mText.setText("transfer start");
            mProgressBar.setProgress(0);//进度条复位
        }

        protected void onCancelled () {//在ui线程执行
            mProgressBar.setProgress(0);//进度条复位
        }



    }


    private class GetBracketListTask extends AsyncTask<Void, Integer, Void> {

        private String fp;

        public GetBracketListTask(String filePath) {
            this.fp = filePath;
        }

        @Override
        protected Void doInBackground(Void... params) {

            File file = new File(fp);
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(file);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            for(int i=0;i<handles.size();i++)
            {
                publishProgress(i*100/handles.size());//将会调用onProgressUpdate(Integer... progress)方法
                ObjectInfo objectInfo = null;
                try {
                    objectInfo = camera.getObjectInfo(handles.get(i));
                } catch (ThetaException e) {
                    e.printStackTrace();
                }
                String filename=objectInfo.getFilename()+"\r\n";
                try {
                    fos.write(filename.getBytes());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            handles.clear();
            return null;
        }


        protected void onProgressUpdate(Integer... progress) {//在调用publishProgress之后被调用，在ui线程执行
            mProgressBar.setProgress(progress[0]);//更新进度条的进度
        }

        protected void onPostExecute(Void result) {//后台任务执行完之后被调用，在ui线程执行
            mProgressBar.setProgress(100);
            mText.setText("complete save file "+fp);
        }

        protected void onPreExecute () {//在 doInBackground(Params...)之前被调用，在ui线程执行
            mText.setText("saving image list");
            mProgressBar.setProgress(0);//进度条复位
        }

        protected void onCancelled () {//在ui线程执行
            mProgressBar.setProgress(0);//进度条复位
        }



    }


    public class SetPropertyCaptureTask extends AsyncTask<Integer, Void, Boolean> {

        public boolean SetProperty(int pptindex, int stindex)
        {
            try {
                switch(pptindex)
                {
                    case 0:
                        camera.setWhiteBalance(wbmap[stindex]);
                        return true;
                    case 1:
                        camera.setExposureIndex(isomap[stindex]);
                        return true;
                    case 2:
                        camera.setShutterSpeed(ssmap[stindex]);
                        return true;
                    case 3:
                        camera.setExposureBiasCompensation((short)evmap[stindex]);
                        return true;
                }
            } catch (ThetaException e) {
                e.printStackTrace();
            }
            return false;
        }

        private int index;

        public SetPropertyCaptureTask(int idx) {
            this.index = idx;
        }

        @Override
        protected Boolean doInBackground(Integer... params) {
            return SetProperty(propertyIdx.get(index),settingIdx.get(index));
        }

        protected void onProgressUpdate(Integer... progress) {//在调用publishProgress之后被调用，在ui线程执行
//            mProgressBar.setProgress(progress[0]);//更新进度条的进度
        }

        protected void onPostExecute(Boolean result) {//后台任务执行完之后被调用，在ui线程执行
            String propertyShortStr=getResources().getStringArray(R.array.pptitems)[propertyIdx.get(index)];
            if(result) {
                mText.setText(propertyShortStr+" "+SettingStr(propertyIdx.get(index), settingIdx.get(index)));
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                new ShootTaskBK(index).execute();
                return;
            }
            else
            {
                mText.setText(propertyShortStr + " " + SettingStr(propertyIdx.get(index), -1));
            }

//            isbusy=-1;

        }

        protected void onPreExecute () {//在 doInBackground(Params...)之前被调用，在ui线程执行
//            mProgressBar.setProgress(0);//进度条复位
//            isbusy=0;
//            resultMsg.clear();
        }

        protected void onCancelled () {//在ui线程执行
//            mProgressBar.setProgress(0);//进度条复位
//            isbusy=-1;
        }

    }



    ////////////////////////////////////////////////////////////////////////////////////////////////
    private static enum ShootResult {
        SUCCESS, FAIL_CAMERA_DISCONNECTED, FAIL_STORE_FULL, FAIL_DEVICE_BUSY
    }


/////////////////////////////////////////////////////////////////////////////////////

    private ArrayList<Integer> handles;

    //////////////////////////////////////////////////////////////////////////

    private class CaptureListenerBK extends PtpipEventListener {
//        private int latestCapturedObjectHandle;
        private boolean objectAdd = false;

        private int index;

        public CaptureListenerBK(int idx) {
            this.index = idx;
        }

        @Override
        public void onObjectAdded(int objectHandle) {
            this.objectAdd = true;
//            this.latestCapturedObjectHandle = objectHandle;
            handles.add(objectHandle);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mText.setText("object added");
                }
            });
        }

        @Override
        public void onCaptureComplete(int transactionId) {
            if (objectAdd) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                        index++;

                        if(index<settingIdx.size())
                        {
                            new SetPropertyCaptureTask(index).execute();
                            return;
                        }

                        mText.setText("complete bracket");

                        SimpleDateFormat sDateFormat   =   new SimpleDateFormat("yyyyMMdd_hhmmss");
                        String fileName =  sDateFormat.format(new java.util.Date());
                        fileName=fileName+".txt";
                        String f = Environment.getExternalStorageDirectory().getPath();//获取SD卡目录
                        File destDir = new File(f+"/"+folder);
                        if (!destDir.exists()) {
                            destDir.mkdirs();
                        }
                        new GetBracketListTask(f+"/"+folder+"/"+fileName).execute();
                    }
                });
            }
        }
    }

    private class ShootTaskBK extends AsyncTask<Void, Void, ShootResult> {

        private int index;

        public ShootTaskBK(int idx) {
            this.index = idx;
        }

        @Override
        protected ShootResult doInBackground(Void... params) {
            CaptureListenerBK postviewListener = new CaptureListenerBK(index);
            try {
                camera.initiateCapture(postviewListener);
                return ShootResult.SUCCESS;
            } catch (ThetaException e) {
                e.printStackTrace();
                if (Response.RESPONSE_CODE_STORE_FULL == e.getStatus())
                    return ShootResult.FAIL_STORE_FULL;

                if (Response.RESPONSE_CODE_DEVICE_BUSY == e.getStatus())
                    return ShootResult.FAIL_DEVICE_BUSY;

                return ShootResult.FAIL_CAMERA_DISCONNECTED;
            }
        }



        @Override
        protected void onPostExecute(ShootResult result) {
            switch (result)
            {
                case FAIL_CAMERA_DISCONNECTED:
                    mText.setText("fail camera disconnect");
                    break;
                case FAIL_STORE_FULL:
                    mText.setText("fail storage full");
                    break;
                case FAIL_DEVICE_BUSY:
                    mText.setText("fail device busy");
                    break;
                case SUCCESS:
                    mText.setText("trigger "+String.valueOf(index+2)+"/"+String.valueOf(settingIdx.size()+1));
                    break;
            }

        }

        protected void onPreExecute () {//在 doInBackground(Params...)之前被调用，在ui线程执行
            mText.setText("start trigger");
//            mProgressBar.setProgress(0);//进度条复位
        }

        protected void onCancelled () {//在ui线程执行
//            mProgressBar.setProgress(0);//进度条复位
        }



    }
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////

    private static final String TAG = "TestKeyEvent";

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent msg){
        Log.v(TAG, "onKeyDown: keyCode = " + keyCode);
        Log.v(TAG, "onKeyDown: String = " + msg.toString());
        switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_UP:
            case KeyEvent.KEYCODE_DPAD_RIGHT:
                break;
            case KeyEvent.KEYCODE_DPAD_DOWN:
            case KeyEvent.KEYCODE_DPAD_LEFT:

                break;
            case KeyEvent.KEYCODE_VOLUME_UP:
            case KeyEvent.KEYCODE_VOLUME_DOWN:
            {
                BracketList();
                handles.clear();
                new ShootTaskBK(-1).execute();
            }
            break;
            default:
                break;
        }

        return super.onKeyDown(keyCode, msg);
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mText = (TextView) findViewById(R.id.textView);

        mButtonP[0].mButton = (Button) findViewById(R.id.button);
        mButtonP[0].Setup(0);

        mButtonP[1].mButton = (Button) findViewById(R.id.button2);
        mButtonP[1].Setup(1);

        mButtonP[2].mButton = (Button) findViewById(R.id.button3);
        mButtonP[2].Setup(2);

        mButtonP[3].mButton = (Button) findViewById(R.id.button4);
        mButtonP[3].Setup(3);

        mButtonP[4].mButton = (Button) findViewById(R.id.button5);
        mButtonP[4].Setup(4);

        mButtonP[5].mButton = (Button) findViewById(R.id.button6);
        mButtonP[5].Setup(5);

        mButtonP[6].mButton = (Button) findViewById(R.id.button7);
        mButtonP[6].Setup(6);


        propertyIdx=new ArrayList<Integer>();
        settingIdx=new ArrayList<Integer>();
//        resultMsg=new ArrayList<String>();
       handles=new ArrayList<Integer>();

        mProgressBar=(ProgressBar)findViewById(R.id.progressBar);
        connectionSwitch = (Switch)findViewById(R.id.switch1);
        connectionSwitch.setOnCheckedChangeListener(new ConnectOnCheckedChangeListener());

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}
